package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrdersMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.utils.HttpClientUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author chensheng
 * @since 2025-08-08
 */
@Service
@Slf4j

public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {

    @Value("${sky.shop.address}")
    private String shopAddress;
    @Value("${sky.baidu.ak}")
    private String ak;

    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    /**
     * 用户下单
     */
    @Transactional
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO oDTO) {
        log.info("用户下单：{}", oDTO);
        //检查地址是否存在
        AddressBook addressBook = addressBookMapper.selectById(oDTO.getAddressBookId());
        if (addressBook == null) {
            //地址不存在
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //检查用户的收获地址是否超出配送范围
        checkOutOfRange(addressBook.getCityName()+ addressBook.getDistrictName()+addressBook.getDetail());
        Long userId = BaseContext.getCurrentId();
        LambdaQueryWrapper<ShoppingCart> shoppingCartWrapper = new LambdaQueryWrapper<ShoppingCart>()
            .eq(ShoppingCart::getUserId, userId);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.selectList(shoppingCartWrapper);
        if (shoppingCartList.isEmpty()) {
            //购物车为空
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //创建订单对象
        Orders orders = new Orders();
        BeanUtils.copyProperties(oDTO, orders);
        //需要设置订单属性
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setPayStatus(Orders.UN_PAID);
        orders.setOrderTime(LocalDateTime.now());
        orders.setUserId(userId);


        //保存订单
        ordersMapper.insert(orders);
        //保存订单详情
        ArrayList<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart shoppingCart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            // 手动复制需要的属性，避免复制购物车的ID
            orderDetail.setName(shoppingCart.getName());
            orderDetail.setOrderId(orders.getId());
            orderDetail.setDishId(shoppingCart.getDishId());
            orderDetail.setSetmealId(shoppingCart.getSetmealId());
            orderDetail.setDishFlavor(shoppingCart.getDishFlavor());
            orderDetail.setNumber(shoppingCart.getNumber());
            orderDetail.setAmount(shoppingCart.getAmount());
            orderDetail.setImage(shoppingCart.getImage());
            orderDetailList.add(orderDetail);
        }
        orderDetailMapper.insert(orderDetailList);

        //清空购物车
        LambdaQueryWrapper<ShoppingCart> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(ShoppingCart::getUserId, userId);
        shoppingCartMapper.delete(deleteWrapper);

        //返回订单数据
        return OrderSubmitVO.builder()
            .id(orders.getId())
            .orderNumber(orders.getNumber())
            .orderAmount(orders.getAmount())
            .orderTime(orders.getOrderTime())
            .build();
    }

    /**
     * 历史订单查询
     */
    @Override
    public PageResult page(Integer page, Integer pageSize, Integer status) {
        log.info("分页查询订单：page={}, pageSize={}, status={}", page, pageSize, status);
        
        // 构造分页条件
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        
        // 构造查询条件
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId, BaseContext.getCurrentId())
            .eq(status != null, Orders::getStatus, status)
            .orderByDesc(Orders::getOrderTime);
        
        // 执行分页查询
        this.page(pageInfo, queryWrapper);
        
        // 转换为OrderVO列表，包含订单详情
        List<OrderVO> orderVOList = pageInfo.getRecords().stream().map(orders -> {
            // 查询订单详情
            LambdaQueryWrapper<OrderDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
            detailQueryWrapper.eq(OrderDetail::getOrderId, orders.getId());
            List<OrderDetail> orderDetails = orderDetailMapper.selectList(detailQueryWrapper);
            
            // 构造OrderVO对象
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            orderVO.setOrderDetailList(orderDetails);
            return orderVO;
        }).collect(Collectors.toList());
        
        // 封装并返回结果
        return PageResult.builder()
            .total(pageInfo.getTotal())
            .records(orderVOList)
            .build();
    }

    /**
     * 订单详情查询
     */
    @Override
    public OrderVO getOrderDetail(Long id) {
        log.info("查询订单详情，订单id为：{}", id);
        // 查询订单基本信息
        Orders orders = ordersMapper.selectById(id);
        
        if (orders != null) {
            // 查询订单详情信息
            LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(OrderDetail::getOrderId, id);
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);
            
            // 构造OrderVO对象并返回
            OrderVO orderVO = new OrderVO();
            // 拷贝订单基本信息
            BeanUtils.copyProperties(orders, orderVO);
            // 设置订单详情列表
            orderVO.setOrderDetailList(orderDetailList);
            
            return orderVO;
        }
        return null;
    }

    /**
     * 取消订单
     */
    @Override
    public void cancleOrder(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());
        ordersMapper.updateById(orders);
    }

    /**
     * 再来一单
     */
    @Override
    public void reOrder(Long id) {
        log.info("再来一单，订单id为：{}", id);
        Orders orders = ordersMapper.selectById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, id));
        if (orderDetailList == null || orderDetailList.isEmpty()) {
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        orders.setId(id + 1);
        ordersMapper.insert(orders);
        orderDetailList.forEach(orderDetail -> orderDetail.setOrderId(orders.getId()));
        orderDetailMapper.insert(orderDetailList);
    }

    /**
     * 订单搜索
     */
    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        log.info("订单搜索：{}", ordersPageQueryDTO);
        Page<Orders> page = new Page<>(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        LambdaQueryWrapper<Orders> pw = new LambdaQueryWrapper<>();
        pw.like(ordersPageQueryDTO.getNumber() != null, Orders::getNumber, ordersPageQueryDTO.getNumber())
                .like(ordersPageQueryDTO.getPhone() != null, Orders::getPhone, ordersPageQueryDTO.getPhone())
                .eq(ordersPageQueryDTO.getStatus() != null, Orders::getStatus, ordersPageQueryDTO.getStatus())
                .ge(ordersPageQueryDTO.getBeginTime() != null, Orders::getOrderTime, ordersPageQueryDTO.getBeginTime())
                .le(ordersPageQueryDTO.getEndTime() != null, Orders::getOrderTime, ordersPageQueryDTO.getEndTime())
                .orderByDesc(Orders::getOrderTime);
        Page<Orders> pageResult = ordersMapper.selectPage(page, pw);
        return PageResult.builder()
                .total(pageResult.getTotal())
                .records(pageResult.getRecords())
                .build();
    }

    /**
     * 各个状态的订单数量统计
     */
    @Override
    public OrderStatisticsVO statistics() {
        log.info("各个状态的订单数量统计");
        // 查询所有订单，按状态分组统计
        List<Orders> ordersList = ordersMapper.selectList(null);
        
        // 初始化各个状态的统计值
        int toBeConfirmed = 0;      // 待接单
        int confirmed = 0;          // 待派送(已接单)
        int deliveryInProgress = 0; // 派送中
        
        // 遍历订单列表，统计各状态订单数量
        if (ordersList != null && !ordersList.isEmpty()) {
            for (Orders orders : ordersList) {
                Integer status = orders.getStatus();
                if (status != null) {
                    if (status.equals(Orders.TO_BE_CONFIRMED)) {
                        // 待接单
                        toBeConfirmed++;
                    } else if (status.equals(Orders.CONFIRMED)) {
                        // 已接单(待派送)
                        confirmed++;
                    } else if (status.equals(Orders.DELIVERY_IN_PROGRESS)) {
                        // 派送中
                        deliveryInProgress++;
                    }
                }
            }
        }
        
        // 构建返回结果
        return OrderStatisticsVO.builder()
                .toBeConfirmed(toBeConfirmed)
                .confirmed(confirmed)
                .deliveryInProgress(deliveryInProgress)
                .build();
    }

    /**
     * 查询订单详情
     */
    @Override
    public OrderVO selectById(Long id) {
        log.info("查询订单详情，订单id为：{}", id);
        Orders orders = ordersMapper.selectById(id);
        if (orders != null) {
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, id));
            OrderVO orderVO = new OrderVO();
            BeanUtils.copyProperties(orders, orderVO);
            orderVO.setOrderDetailList(orderDetailList);
            return orderVO;
        }
        return null;
    }

    /**
     * 接单
     */
    @Override
    public void confirm(OrdersDTO ordersDTO) {
        log.info("接单，订单id为：{}", ordersDTO.getId());
        Orders orders = new Orders();
        orders.setId(ordersDTO.getId());
        orders.setStatus(Orders.CONFIRMED);
        ordersMapper.updateById(orders);
    }

    /**
     * 拒单
     */
    @Override
    public void rejection(Long id, String rejectionReason) {
        log.info("拒单，订单id为：{}", id);
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.CANCELLED);
        orders.setRejectionReason(rejectionReason);
        ordersMapper.updateById(orders);
    }
    /**
     * 管理员取消订单
     */
    @Override
    public void cancleOrderByAdmin(Long id, String cancelReason) {
        log.info("管理员取消订单，订单id为：{}", id);
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.CANCELLED);
        orders.setCancelReason(cancelReason);
        orders.setCancelTime(LocalDateTime.now());
        ordersMapper.updateById(orders);
    }

    /**
     * 派送订单
     */
    @Override
    public void delivery(Long id) {
        log.info("派送订单，订单id为：{}", id);
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        ordersMapper.updateById(orders);
    }

    /**
     * 完成订单
     */
    @Override
    public void complete(Long id) {
        log.info("完成订单，订单id为：{}", id);
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.COMPLETED);
        ordersMapper.updateById(orders);
    }
    /**
     * 订单支付
     */
    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) {
        log.info("订单支付：{}", ordersPaymentDTO);
        OrderPaymentVO orderPaymentVO = new OrderPaymentVO();
        orderPaymentVO.setNonceStr(String.valueOf(System.currentTimeMillis()));
        orderPaymentVO.setPackageStr("1111");
        orderPaymentVO.setSignType("MD5");
        orderPaymentVO.setTimeStamp(String.valueOf(System.currentTimeMillis()));
        return orderPaymentVO;

    }

    /**
     * 检查客户的收货地址是否超出配送范围
     * @param address
     */
    private void checkOutOfRange(String address) {
        Map map = new HashMap();
        map.put("address",shopAddress);
        map.put("output","json");
        map.put("ak",ak);

        //获取店铺的经纬度坐标
        String shopCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        JSONObject jsonObject = JSON.parseObject(shopCoordinate);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("店铺地址解析失败");
        }

        //数据解析
        JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
        String lat = location.getString("lat");
        String lng = location.getString("lng");
        //店铺经纬度坐标
        String shopLngLat = lat + "," + lng;

        map.put("address",address);
        //获取用户收货地址的经纬度坐标
        String userCoordinate = HttpClientUtil.doGet("https://api.map.baidu.com/geocoding/v3", map);

        jsonObject = JSON.parseObject(userCoordinate);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("收货地址解析失败");
        }

        //数据解析
        location = jsonObject.getJSONObject("result").getJSONObject("location");
        lat = location.getString("lat");
        lng = location.getString("lng");
        //用户收货地址经纬度坐标
        String userLngLat = lat + "," + lng;

        map.put("origin",shopLngLat);
        map.put("destination",userLngLat);
        map.put("steps_info","0");

        //路线规划
        String json = HttpClientUtil.doGet("https://api.map.baidu.com/directionlite/v1/driving", map);

        jsonObject = JSON.parseObject(json);
        if(!jsonObject.getString("status").equals("0")){
            throw new OrderBusinessException("配送路线规划失败");
        }

        //数据解析
        JSONObject result = jsonObject.getJSONObject("result");
        JSONArray jsonArray = (JSONArray) result.get("routes");
        Integer distance = (Integer) ((JSONObject) jsonArray.get(0)).get("distance");

        if(distance > 5000){
            //配送距离超过5000米
            throw new OrderBusinessException("超出配送范围");
        }
    }
}